﻿using System;
using Hammock;
using Hammock.Authentication.OAuth;
using WeiboPlus.Service;
using WeiboPlus.Models;
using System.Diagnostics;
using Newtonsoft.Json.Linq;
using Hammock.Web;

namespace WeiboPlus.Sina
{
    public class SinaOAuthService : OAuthServiceBase
    {
        public SinaOAuthService()
        {
            Provider = SinaSNSProviderFactory.Instance.GetProvider();
        }

        public override void RequestToken(Action<SNSAccount, SNSResult> action)
        {
            string authUrl = string.Format("{0}{1}?client_id={2}&display=mobile&redirect_uri={3}&response_type=code", Provider.AuthSettings.CLIENT, Provider.AuthSettings.PATH_AUTHORIZE, Provider.AuthSettings.CONSUMER_KEY, Provider.AuthSettings.CALLBACK_URL);
            Account.AuthorizeURL = authUrl;
            action(Account, new SNSResult() { IsSuccess = true, Message = "Require Request Token Success" });
            //base.RequestToken(action);
        }

        public override void AccessToken(Action<SNSAccount, SNSResult> action)
        {
            var request = new RestRequest()
            {
                Path = Provider.AuthSettings.PATH_ACCESS_TOKEN
            };
            
            request.AddParameter("grant_type", "authorization_code");
            request.AddParameter("code", Account.PIN);
            //request.AddParameter("redirect_uri", "");
            request.AddParameter("client_id", Provider.AuthSettings.CONSUMER_KEY);
            request.AddParameter("client_secret", Provider.AuthSettings.CONSUMER_KEY_SECRET);

            Execute((res) =>
            {
                Debug.WriteLine(res.Content);

                JObject o = JObject.Parse(res.Content);
                string msg;
                if (ValidateResponse(res, out msg) == 0)
                {
                    //TO-DO
                    if (action != null)
                    {
                        action(Account, new SNSResult() { IsSuccess = false, Message = msg });
                    }
                }
                string access_token = (string)o.SelectToken("access_token");
                int expires_in = (int)o.SelectToken("expires_in");
                string refresh_token = (string)o.SelectToken("refresh_token");
                string uid = (string)o.SelectToken("uid");

                Account.AccessToken = access_token;
                Account.ExpiresIn = expires_in;
                Account.RefreshToken = refresh_token;
                Account.UserName = uid;
                //Account.Scope = scope;
                Account.IsBind = true;

                if (action != null)
                {
                    action(Account, new SNSResult() { IsSuccess = true, Message = msg });
                }

                //Test refresh token
                //AccessTokenRefresh(null);
                

            }, request);
            //base.AccessToken(action);
        }

        protected override RestClient CreateRestClient()
        {
            var client = base.CreateRestClient();
            client.Method = WebMethod.Post;
            
            return client;
        }

        public override void AccessTokenRefresh(Action<SNSAccount, SNSResult> action)
        {
            //base.AccessTokenRefresh(action);
            var request = new RestRequest()
            {
                Path = Provider.AuthSettings.PATH_ACCESS_TOKEN
            };

            request.AddParameter("grant_type", "refresh_token");
            request.AddParameter("access_token", Account.AccessToken);
            //request.AddParameter("code", Account.PIN);
            //request.AddParameter("redirect_uri", "");
            request.AddParameter("client_id", Provider.AuthSettings.CONSUMER_KEY);
            request.AddParameter("client_secret", Provider.AuthSettings.CONSUMER_KEY_SECRET);

            Execute((res) =>
            {
                Debug.WriteLine(res.Content);

                JObject o = JObject.Parse(res.Content);
                string msg;
                if (ValidateResponse(res, out msg) == 0)
                {
                    //TO-DO
                    if (action != null)
                    {
                        action(Account, new SNSResult() { IsSuccess = false, Message = msg });
                    }
                }
                string access_token = (string)o.SelectToken("access_token");
                int expires_in = (int)o.SelectToken("expires_in");
                string refresh_token = (string)o.SelectToken("refresh_token");
                string uid = (string)o.SelectToken("uid");

                Account.AccessToken = access_token;
                Account.ExpiresIn = expires_in;
                Account.RefreshToken = refresh_token;
                Account.UserName = uid;
                //Account.Scope = scope;
                Account.IsBind = true;

                if (action != null)
                {
                    action(Account, new SNSResult() { IsSuccess = true, Message = msg });
                }
            }, request);

        }

    }
}
